package com.global.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.global.base.StringUtil;
import com.global.dao.GridColumnDao;
import com.global.dao.GridDao;
import com.global.dao.ReportDao;
import com.global.dao.jdbc.GenericJdbcDao;
import com.global.model.DataSourceX;
import com.global.model.DataSourceXColumn;
import com.global.model.Grid;
import com.global.model.GridColumn;
import com.global.model.QueryParameterDefinition;
import com.global.model.Report;
import com.global.model.Who;
import com.global.service.AbstractService;
import com.global.service.DataSourceXDefinitionService;
import com.global.service.ReportDefinitionService;
import com.global.vo.BooleanResult;
import com.global.vo.DBColumn;
import com.global.vo.QueryParameter;
import com.global.vo.QueryType;

@Service("reportDefinitionService")
public class ReportDefinitionServiceImpl extends AbstractService implements ReportDefinitionService {
	
	@Autowired
	ReportDao reportDao;
	@Autowired
	GridDao gridDao;
	@Autowired
	GridColumnDao gridColumnDao;
	
	@Autowired
	GenericJdbcDao jdbcDao;
	
	@Autowired
	DataSourceXDefinitionService dataSourceXService;
	
	/**
	 * {@inheritDoc}
	 */
	public Report registerOrUpdateReport(Report rptx){
		return reportDao.saveReport(rptx);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public boolean registerOrUpdateReportBatch(List<Report> reportList){
		return reportDao.saveBatchReport(reportList);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public Grid registerOrUpdateGrid(Grid grid){
		return gridDao.saveGrid(grid);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public boolean registerOrUpdateGridBatch(List<Grid> gridList){
		return gridDao.saveBatchGrids(gridList);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public boolean registerOrUpdateGridColumnBatch(List<GridColumn> gridColumnList){
		return gridColumnDao.saveBatchGridColumns(gridColumnList);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public BooleanResult registerOrUpdateGridColumns(Grid grid, Who who){
		List<String> messageList = new ArrayList<String>();
		
		if(grid==null){
			messageList.add("Grid为空，则无法刷新Grid！");
        	return new BooleanResult(false, StringUtil.getString(messageList));
        }
		
        grid = registerOrUpdateGrid(grid);
        
        //从DB检索出最新的GridColumn清单
        List<GridColumn> allGridColumnList = getAllGridColumnList(grid);
        grid.setGridColumnList(allGridColumnList);
        
        int maxDisplayIndex = 0;
        for(GridColumn g : allGridColumnList){
        	if(g.getDisplayIndex()>maxDisplayIndex){
        		maxDisplayIndex = g.getDisplayIndex();
        	}
        }
        
        DataSourceX dataSourceX = grid.getDataSourceX();
        
        //从DB中取出数据源中的字段清单
        List<DataSourceXColumn> dataSourceXColumnList = dataSourceXService.getDataSourceXColumnList(dataSourceX);
		if(dataSourceXColumnList.isEmpty()){
			messageList.add("Grid绑定的数据源【" + dataSourceX.getDescription() + "】中没有配置字段，则无法刷新Grid！");
			return new BooleanResult(false, StringUtil.getString(messageList));
		}else{
			BooleanResult checkDataSourceX = dataSourceXService.checkDataSourceX(dataSourceX);
			messageList.add(checkDataSourceX.getMessage());
			if(!checkDataSourceX.getResult()){
				return new BooleanResult(false, StringUtil.getString(messageList));
			}
		}
		
		if(allGridColumnList.isEmpty()){
			//需要保存的GridColumn清单
			List<GridColumn> newGridColumnList = new ArrayList<GridColumn>(dataSourceXColumnList.size());
			for(DataSourceXColumn d : dataSourceXColumnList){
				GridColumn gridColumn = new GridColumn();
				
				gridColumn.setGrid(grid);
				gridColumn.setDataSourceXColumn(d);
				gridColumn.setLabel(d.getAlias());
				gridColumn.setDisplayIndex(d.getDisplayIndex()*10);
				gridColumn.setDisplayMaxWidth(20);
				gridColumn.setWho(who);
				
				newGridColumnList.add(gridColumn);
			}
			
			return new BooleanResult(registerOrUpdateGridColumnBatch(newGridColumnList));
		}else{
			//验证GridColumn组件绑定的数据源是否有效			
			List<DBColumn> dbColumnList = new ArrayList<DBColumn>();
			if(dataSourceX.getQueryType().equalsIgnoreCase(QueryType.QueryType_StaticSQL)){
				dbColumnList = jdbcDao.getStaticSQLMetaData(dataSourceX.getSql());
			}else if(dataSourceX.getQueryType().equalsIgnoreCase(QueryType.QueryType_NamedParameterSQL)){
				List<QueryParameter> namedParameters = new ArrayList<QueryParameter>();
				for(int i=0; i < dataSourceX.getFixedParameterDefinitions().size(); i++){
					QueryParameterDefinition queryParameterDf = dataSourceX.getFixedParameterDefinitions().get(i);
					namedParameters.add(new QueryParameter(queryParameterDf.getName(), null));			
				}
				dbColumnList = jdbcDao.getNamedParameterSQLMetaData(dataSourceX.getSql(), namedParameters);
			}
			List<String> invalidateNameList = new ArrayList<String>();
			for(GridColumn g: grid.getGridColumnList()){
				boolean isExist = false;
				for(DBColumn d : dbColumnList){
					if(g.getDataSourceXColumn().getAlias().equalsIgnoreCase(d.getAlias())){
						isExist = true;							
						break;
					}
				}
				if(!isExist){
					invalidateNameList.add(g.getLabel());
				}
			}				
			if(!invalidateNameList.isEmpty()){
				messageList.add("GridColumn组件" + invalidateNameList.toString() + "绑定的数据源字段在数据源【" + dataSourceX.getDescription() + "】中已经不合法，请手动删除，否则无法正常使用！");
			}
			
			//数据源如果是新增的，则新增GridColumn
			List<GridColumn> newGridColumnList = new ArrayList<GridColumn>();
			int newLabelNum = 1;
			for(DataSourceXColumn d : dataSourceXColumnList){
				boolean isExist = false;

				for(GridColumn g: grid.getGridColumnList()){
					if(g.getDataSourceXColumn().equals(d)){
						isExist = true;
						
						break;
					}
				}

				if(!isExist){
					maxDisplayIndex = maxDisplayIndex + 10;
					
					String label = d.getAlias();
					for(GridColumn g : grid.getGridColumnList()){
						if(g.getLabel().equalsIgnoreCase(label)){
							label = label + (newLabelNum++);
							break;
						}
					}
					
					GridColumn gridColumn = new GridColumn();
					
					gridColumn.setGrid(grid);
					gridColumn.setDataSourceXColumn(d);
					gridColumn.setLabel(label);
					gridColumn.setDisplayIndex(maxDisplayIndex);
					gridColumn.setDisplayMaxWidth(20);
					gridColumn.setWho(who);
					
					newGridColumnList.add(gridColumn);
				}
			}
			
			boolean is1 = registerOrUpdateGridColumnBatch(newGridColumnList);			
			boolean is2 = newGridColumnList.addAll(0, grid.getGridColumnList());
			
			//刷新缓存
			grid.setGridColumnList(newGridColumnList);
	        
			return new BooleanResult(is1 && is2, StringUtil.getString(messageList));
		}
	}
	
	/**
	 * {@inheritDoc}
	 */
	public BooleanResult deleteReport(Report report){
		String message = "";
		
		if(report!=null){
			if(report.getId()!=null){
				if(report.getGridList().isEmpty()){
					gridDao.remove(report.getId());
					
					return new BooleanResult(true);
				}else{
					message = "report中存在Grid，则无法删除当前report【" + report.getDescription() + "】。";
				}
			}else{
				message = "对象report的主键为空，则无法删除。";
			}
		}else{
			message = "report为空，则无法删除。";
		}
		
		return new BooleanResult(false, message);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public BooleanResult deleteGrid(Grid grid){
		String message = "";
		
		if(grid!=null){
			if(grid.getId()!=null){
				if(grid.getGridColumnList().isEmpty()){
					gridDao.remove(grid.getId());
					
					return new BooleanResult(true);
				}else{
					message = "Grid中存在组件，则无法删除当前Grid【" + grid.getDescription() + "】。";
				}
			}else{
				message = "对象grid的主键为空，则无法删除。";
			}
		}else{
			message = "grid为空，则无法删除。";
		}
		
		return new BooleanResult(false, message);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public BooleanResult deleteGridColumn(GridColumn gridColumn){
		String message = "";
		
		if(gridColumn!=null){
			if(gridColumn.getId()!=null){
				gridDao.remove(gridColumn.getId());
				return new BooleanResult(true);
			}else{
				message = "对象gridColumn主键为空，则无法删除。";
			}
		}else{
			message = "gridColumn为空，则无法删除。";			
		}
		
		return new BooleanResult(false, message);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public List<Report> getReportList(){
		return reportDao.getAll();
	}
	
	/**
	 * {@inheritDoc}
	 */
	public List<Grid> getGridList(Report report){
		List<Grid> gridList = new ArrayList<Grid>();
		if(report!=null && report.getId()!=null){
			gridDao.getGridList(report);
		}
		
		return gridList;
	}
	
	/**
	 * {@inheritDoc}
	 */
	public List<GridColumn> getAllGridColumnList(Grid grid){			
		return gridColumnDao.getAllGridColumnList(grid);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public List<GridColumn> getDispalyGridColumnList(Grid grid){
		return gridColumnDao.getDispalyGridColumnList(grid);
	}
}
